using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace SPGE
{
    public class GameItemComposite : GameItemContainer, IGameItem
    {
        public Action<IGameItem> OnLoadStart
        { get; set; }
        public Action<IGameItem> OnLoadEnd
        { get; set; }
        public Action<IGameItem> OnRenderStart
        { get; set; }
        public Action<IGameItem> OnRenderEnd
        { get; set; }
        public Action<IGameItem> OnUpdateStart
        { get; set; }
        public Action<IGameItem> OnUpdateEnd
        { get; set; }

        public bool IsActive
        { get; set; }

        public float RenderLevel
        { get; set; }

        public Vector2 Position
        { get; set; }
        public virtual Vector2 Size
        { get; set; }
        public Vector2 Scaling
        { get; set; }

        public float Rotation
        { get; set; }
        public Vector2 Origin
        { get; set; }

        public SpriteBatchUse SpriteUse
        {
            get { return SpriteBatchUse.EndedSpriteBatch; }
            set { }
        }

        float? updateOrder = null;
        public override float UpdateOrder
        {
            get { return updateOrder ?? RenderLevel; }
            set { updateOrder = value; }
        }

        public GameItemComposite(Func<IEnumerable<IGameItem>> getItems)
            :base(getItems)
        {
            IsVisible = true;
            IsActive = true;
        }

        public GameItemComposite(IEnumerable<IGameItem> items)
            : this(() => { return items; })
        { 
        }

        protected GameItemComposite()
        {
            IsActive = true;
            IsVisible = true;
        }

        /// <summary>
        /// Setups the dispacement calls.
        /// </summary>
        private void SetupDispacementCalls()
        {
            float factor = 10000f;
            foreach (var item in Items)
            {
                Action<IGameItem> start = (IGameItem gi) =>
                {
                    gi.Position = gi.Position + Position;
                    gi.RenderLevel = RenderLevel + (gi.RenderLevel / factor);
                };
                Action<IGameItem> end = (IGameItem gi) =>
                {
                    gi.Position = gi.Position - Position;
                    gi.RenderLevel = (gi.RenderLevel - RenderLevel) * factor;
                };
                item.OnRenderStart += start;
                item.OnUpdateStart += start;
                item.OnRenderEnd += end;
                item.OnUpdateEnd += end;
            }

        }

        bool ItemsSetUp = false;
        public override void Initialize()
        {
            if (!ItemsSetUp)
            {
                SetupDispacementCalls();
                ItemsSetUp = true;
            }

            base.Initialize();
        }

        public override void Draw(GameTime gameTime, Microsoft.Xna.Framework.Graphics.SpriteBatch sb)
        {
            if (OnRenderStart != null)
                OnRenderStart(this);

            base.Draw(gameTime, sb);

            if (OnRenderEnd != null)
                OnRenderEnd(this);
        }
    }
}
